﻿using JNPF.Basics.Models;
using JNPF.Data;
using JNPF.Data.Util;
using JNPF.Utils;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JNPF.Basics.Logic
{
    /// <summary>
    /// 系统消息
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2017-12-27 
    /// </summary>
    internal class MessageService : DataFactory, MessageIService
    {
        /// <summary>
        /// 列表（通知公告）
        /// </summary>
        /// <param name="requestParam">请求参数</param>
        /// <returns></returns>
        public async Task<PageResult<MessageEntity>> GetNoticeList(PageInput requestParam)
        {
            using (var db = this.Basic)
            {
                var queryWhere = ExtLinq.True<MessageEntity>().And(m => m.Type == 1);
                var queryParam = requestParam.queryJson.ToObject();
                //关键词（消息标题）
                if (!requestParam.keyword.IsEmpty())
                {
                    queryWhere = queryWhere.And(m => m.Title.Contains(requestParam.keyword));
                }

                return await db.GetIQueryable<MessageEntity>().Where(queryWhere).OrderByDescending(t => t.LastModifyTime).GetPageResultAsync(requestParam);
            }
        }
        /// <summary>
        /// 列表（通知公告/系统消息/私信消息）
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <param name="userId">当前用户</param>
        /// <param name="type">类别</param>
        /// <returns></returns>
        public async Task<PageResult<MessageEntity>> GetMessageList(PageInput input, string userId, string type = null)
        {
            using (var db = this.Basic)
            {
                var parameters = new List<DbParameter>();
                StringBuilder dbSql = new StringBuilder();
                dbSql.Append(@" SELECT 
                                m.F_Id, 
                                m.F_Title, 
                                m.F_Type, 
                                r.F_IsRead, 
                                m.F_CreatorTime, 
                                m.F_CreatorUserId,
                                m.F_LastModifyTime
                                FROM Base_Message m LEFT JOIN Base_MessageReceive r ON r.F_MessageId = m.F_Id
                                WHERE r.F_UserId = @userId");
                parameters.Add(DataHelper.CreateParameter("@userId", userId));
                //关键词（消息标题）
                if (!input.keyword.IsEmpty())
                {
                    dbSql.Append(" AND m.F_Title like @keyword");
                    parameters.Add(DataHelper.CreateParameter("@keyword", '%' + input.keyword + '%'));
                }
                //消息类别
                if (!string.IsNullOrEmpty(type))
                {
                    dbSql.Append(" AND m.F_Type = @type");
                    parameters.Add(DataHelper.CreateParameter("@type", type));
                }
                input.sidx = "F_LastModifyTime";
                return await PageHelper.GetPageResultAsync<MessageEntity>(db, input, dbSql.ToString(), parameters.ToArray());


            }
        }
        /// <summary>
        /// 信息
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        public async Task<MessageEntity> GetInfo(string id)
        {
            using (var db = this.Basic)
            {
                return await db.GetEntityAsync<MessageEntity>(m => m.Id == id);
            }
        }
        /// <summary>
        /// 默认消息
        /// </summary>
        /// <param name="type">类别:1-通知公告/2-系统消息</param>
        /// <returns></returns>
        public async Task<MessageEntity> GetInfoDefault(int type)
        {
            using (var db = this.Basic)
            {
                return await db.GetEntityAsync<MessageEntity>(m => m.Type == type);
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">实体对象</param>
        public async Task Delete(MessageEntity entity)
        {
            using (var db = this.Basic)
            {
                await db.BeginTransactionAsync();
                await db.DeleteAsync(entity);
                db.Delete<MessageReceiveEntity>(m => m.MessageId == entity.Id);
                await db.CommitTransactionAsync();
            }
        }
        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity">实体对象</param>
        public async Task Create(MessageEntity entity)
        {
            using (var db = this.Basic)
            {
                await db.InsertAsync(entity);
            }
        }
        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="receiveEntityList">收件用户</param>
        public async Task Create(MessageEntity entity, List<MessageReceiveEntity> receiveEntityList)
        {
            using (var db = this.Basic)
            {
                await db.InsertAsync(entity);
                await db.InsertAsync(receiveEntityList);
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity">实体对象</param>
        public async Task Update(MessageEntity entity)
        {
            using (var db = this.Basic)
            {
                await db.UpdateAsync(entity);
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="receiveEntityList">收件用户</param>
        public async Task Update(MessageEntity entity, List<MessageReceiveEntity> receiveEntityList)
        {
            using (var db = this.Basic)
            {
                await db.UpdateAsync(entity);
                await db.InsertAsync(receiveEntityList);
            }
        }
        /// <summary>
        /// 消息已读（单条）
        /// </summary>
        /// <param name="userId">当前用户</param>
        /// <param name="messageId">消息主键</param>
        public async Task MessageRead(string userId, string messageId)
        {
            using (var db = this.Basic)
            {
                var entity = await db.GetEntityAsync<MessageReceiveEntity>(m => m.UserId == userId && m.MessageId == messageId);
                if (entity != null)
                {
                    entity.IsRead = 1;
                    entity.ReadCount = entity.ReadCount == null ? 1 : entity.ReadCount + 1;
                    entity.ReadTime = DateTime.Now;
                    await db.UpdateAsync(entity);
                }
            }
        }
        /// <summary>
        /// 消息已读（全部）
        /// </summary>
        /// <param name="userId">当前用户</param>
        public async Task MessageRead(string userId)
        {
            using (var db = this.Basic)
            {
                await db.BeginTransactionAsync();
                var entitys = await db.GetListAsync<MessageReceiveEntity>(m => m.UserId == userId && m.IsRead == 0);
                if (entitys.Count > 0)
                {
                    foreach (var entity in entitys)
                    {
                        entity.IsRead = 1;
                        entity.ReadCount = entity.ReadCount == null ? 1 : entity.ReadCount + 1;
                        entity.ReadTime = DateTime.Now;
                        db.Update(entity);
                    }
                }
                await db.CommitTransactionAsync();
            }
        }
        /// <summary>
        /// 删除记录
        /// </summary>
        /// <param name="userId">当前用户</param>
        /// <param name="messageIds">消息Id</param>
        public async Task DeleteRecord(string userId, List<string> messageIds)
        {
            using (var db = this.Basic)
            {
                await db.BeginTransactionAsync();
                foreach (var messageId in messageIds)
                {
                    db.Delete<MessageReceiveEntity>(m => m.UserId == userId && m.MessageId == messageId);
                }
                await db.CommitTransactionAsync();
            }
        }
        /// <summary>
        /// 获取未读数量（含 通知公告、系统消息）
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <returns></returns>
        public async Task<int> GetUnreadCount(string userId)
        {
            using (var db = this.Basic)
            {
                return await db.GetCountAsync<MessageReceiveEntity>(m => m.UserId == userId && m.IsRead == 0);
            }
        }
        /// <summary>
        /// 获取公告未读数量
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <returns></returns>
        public async Task<int> GetUnreadNoticeCount(string userId)
        {
            using (var db = this.Basic)
            {
                var parameters = new List<DbParameter>();
                StringBuilder dbSql = new StringBuilder();
                dbSql.Append(@" SELECT COUNT(1)
                                FROM Base_MessageReceive r
	                                LEFT JOIN Base_Message m ON m.F_Id = r.F_MessageId
                                WHERE 1 = 1
	                                AND r.F_UserId = @userId
                                    AND r.F_IsRead = 0
	                                AND m.F_Type = 1");
                parameters.Add(DataHelper.CreateParameter("@userId", userId));
                return (await db.ExecuteScalarAsync(dbSql.ToString(), parameters.ToArray())).ToInt();

            }
        }
        /// <summary>
        /// 获取消息未读数量
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <returns></returns>
        public async Task<int> GetUnreadMessageCount(string userId)
        {
            using (var db = this.Basic)
            {
                var parameters = new List<DbParameter>();
                StringBuilder dbSql = new StringBuilder();
                dbSql.Append(@" SELECT COUNT(1)
                                FROM Base_MessageReceive r
	                                LEFT JOIN Base_Message m ON m.F_Id = r.F_MessageId
                                WHERE 1 = 1
	                                AND r.F_UserId = @userId
                                    AND r.F_IsRead = 0
	                                AND m.F_Type = 2");
                parameters.Add(DataHelper.CreateParameter("@userId", userId));
                return (await db.ExecuteScalarAsync(dbSql.ToString(), parameters.ToArray())).ToInt();
            }
        }
    }
}